package root.plumbum2;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import root.repositorios.HistoricoUsuario;
import root.repositorios.RepositorioEmprestimo;
import root.repositorios.RepositorioInteresse;
import root.repositorios.RepositorioInterface;
import root.repositorios.RepositorioItem;
import root.repositorios.RepositorioPublicacao;
import root.repositorios.RepositorioRequisicaoEmprestimo;
import root.repositorios.RepositorioTopicos;
import root.repositorios.RepositorioUsuario;

public class Usuario implements Comparable<Usuario> {

	private String login;
	private String nome;
	private String endereco;
	private RepositorioInterface<Usuario> repositorioAmigos;
	private RepositorioInterface<Usuario> repositorioRequisicoesAmizade;
	private RepositorioInterface<Item> repositorioItem;
	private RepositorioInterface<Emprestimo> repositorioEmprestimo;
	private RepositorioInterface<Topico> repositorioMensagem;
	private RepositorioInterface<Interesse> repositorioInteresse;
	private RepositorioInterface<Emprestimo> repositorioRequisicaoEmprestimo;
	private int reputacao;
	private HistoricoUsuario myHistorico;
	private RepositorioInterface<Publicacao> repositorioPublicacoes;

	public Usuario(String login, String nome, String endereco) throws Exception {
		VerificadorDadosEntrada
				.verificaLoginNomeEndereco(login, nome, endereco);
		this.login = login;
		this.nome = nome;
		this.endereco = endereco;
		this.repositorioRequisicoesAmizade = new RepositorioUsuario();
		this.repositorioAmigos = new RepositorioUsuario();
		this.repositorioItem = new RepositorioItem();
		this.repositorioEmprestimo = new RepositorioEmprestimo();
		this.repositorioMensagem = new RepositorioTopicos();
		this.repositorioInteresse = new RepositorioInteresse();
		this.repositorioRequisicaoEmprestimo = new RepositorioRequisicaoEmprestimo();
		this.reputacao = 0;
		this.myHistorico = new HistoricoUsuario();
		this.repositorioPublicacoes = new RepositorioPublicacao();
	}

	public RepositorioInterface getRepositorioPublicacao() {
		return this.repositorioPublicacoes;
	}

	public String getLogin() {
		return login;
	}

	public String getNome() {
		return this.nome;
	}

	public String getEndereco() {
		return this.endereco;
	}

	public RepositorioInterface<Item> getRepositorioItem2() {
		return repositorioItem;
	}

	public List<Usuario> getRepositorioAmigos() {
		return this.repositorioAmigos.getRepositorio();
	}

	public List<Usuario> getRepositorioRequisicoesAmizade() {
		return this.repositorioRequisicoesAmizade.getRepositorio();
	}

	public List<Item> getRepositorioItem() {
		return this.repositorioItem.getRepositorio();
	}

	public List<Emprestimo> getRepositorioEmprestimo() {
		return this.repositorioEmprestimo.getRepositorio();
	}

	public HistoricoUsuario getMyHistorico() {
		return this.myHistorico;
	}

	public List<Emprestimo> getRepositorioEmprestimo(String tipo) {
		if (tipo.equals("emprestador")) {
			return ((RepositorioEmprestimo) repositorioEmprestimo)
					.getListaEmpEmprestador();
		} else if (tipo.equals("beneficiado")) {
			return ((RepositorioEmprestimo) repositorioEmprestimo)
					.getListaEmpBeneficiado();
		} else {
			return ((RepositorioEmprestimo) repositorioEmprestimo)
					.getRepositorio();
		}
	}

	public RepositorioInterface<Emprestimo> getRepositorioEmprestimo2() {
		return this.repositorioEmprestimo;
	}

	public List<Emprestimo> getListBeneficiado() {
		return ((RepositorioEmprestimo) this.repositorioEmprestimo)
				.getListaEmpBeneficiado();
	}

	public List<Emprestimo> getListEmprestador() {
		return ((RepositorioEmprestimo) this.repositorioEmprestimo)
				.getListaEmpEmprestador();
	}

	private RepositorioInterface<Topico> getRepositorioMensagem() {
		return repositorioMensagem;
	}

	public List<Topico> getRepositorioMensagem(String tipo) {
		List<Topico> listaTopicos = new ArrayList<Topico>();
		for (Topico t : ((RepositorioTopicos) repositorioMensagem)
				.getRepositorio()) {
			if (t.getTipo().equals(tipo)) {
				listaTopicos.add(t);
			}
		}
		return listaTopicos;
	}

	public void addRequisicao(Usuario user) throws Exception {
		if (saoAmigos(user)) {
			throw new Exception("Os usuários já são amigos");
		} else if (getRepositorioRequisicoesAmizade().contains(user)) {
			throw new Exception("Requisição já solicitada");
		}

		this.repositorioRequisicoesAmizade.insert(user);
	}

	public void addAmigo(Usuario user) {
		this.repositorioAmigos.insert(user);
		this.repositorioRequisicoesAmizade.remove(user);
	}

	public void aprovarAmizade(Usuario usuario2) throws Exception {
		if (usuario2 == null)
			throw new Exception("Usuário inexistente");
		if (saoAmigos(usuario2))
			throw new Exception("Os usuários já são amigos");
		else if (!getRepositorioRequisicoesAmizade().contains(usuario2)) {
			throw new Exception("Requisição de amizade inexistente");
		}
		usuario2.addAmigo(this);
		addAmigo(usuario2);
		myHistorico.addAtividade(getNome() + " e " + usuario2.getNome()
				+ " são amigos agora");
		usuario2.getMyHistorico().addAtividade(
				usuario2.getNome() + " e " + getNome() + " são amigos agora");
	}

	public boolean saoAmigos(Usuario user) {
		return getRepositorioAmigos().contains(user);
	}

	public String getAmigos() {
		String retorno = "";
		for (Usuario user : getRepositorioAmigos()) {
			retorno += user.getLogin() + "; ";
		}
		return retorno.length() > 0 ? retorno
				.substring(0, retorno.length() - 2)
				: "O usuário não possui amigos";
	}

	public String getItens() {
		String retorno = "";
		for (Item item : getRepositorioItem()) {
			retorno += item.getName() + "; ";
		}
		return retorno.length() > 0 ? retorno
				.substring(0, retorno.length() - 2)
				: "O usuário não possui itens cadastrados";
	}

	// public String cadastrarItem(String name,String description, String
	// category) throws Exception {
	// Item item = new Item(name, description, category);
	// this.repositorioItem.insert(item);
	// return item.getIDItem();
	// }

	public String cadastrarItem(Item item) {
		this.repositorioItem.insert(item);
		myHistorico.addAtividade(getNome() + " cadastrou " + item.getName());
		return item.getIDItem();
	}

	public String getAtributoItem(String idItem, String atributo)
			throws Exception {

		Item item = ((RepositorioItem) this.repositorioItem).search(idItem);
		return item.getAtributo(atributo);
	}

	public String getAtributoItemOutException(String idItem, String atributo) {

		Item item = ((RepositorioItem) this.repositorioItem)
				.searchOutException(idItem);
		return item == null ? null : item.getAtributo(atributo);
	}

	// public boolean ehDono(String idItem){
	// return(idItem.equals(((RepositorioItem)getRepositorioItem()).searchOutException(idItem)));
	// }

	public String getEmprestimos(String tipo) throws Exception {
		VerificadorDadosEntrada.verificaTipoEmprestimo(tipo);
		List<Emprestimo> aux = null;

		if (tipo.equals("beneficiado")) {
			aux = (((RepositorioEmprestimo) this.repositorioEmprestimo)
					.getListaEmpBeneficiado());
		} else if (tipo.equals("emprestador")) {
			aux = ((RepositorioEmprestimo) this.repositorioEmprestimo)
					.getListaEmpEmprestador();
		} else if (tipo.equals("todos")) {
			aux = (((RepositorioEmprestimo) this.repositorioEmprestimo)
					.getRepositorio());
		}
		return concatenaInfoEmprestimo(aux);
	}

	private String concatenaInfoEmprestimo(List<Emprestimo> listaEmprestimo) {

		String retorno = "";
		for (Emprestimo e : listaEmprestimo) {
			if (e.getAprovado()) {
				retorno += e.getItem().getDono() + "-"
						+
						// getLogin()+"-"+
						e.getPedinte() + ":" + e.getItem().getName() + ":"
						+ e.getStatus() + "; ";
			}
		}
		return retorno.length() > 0 ? retorno
				.substring(0, retorno.length() - 2)
				: "Não há empréstimos deste tipo";
	}

	public String requisitarEmprestimo(Usuario dono, String idItem,
			int duracao, String pedinte) throws Exception {

		if (duracao <= 0)
			throw new Exception("Duracao inválida");

		if (!saoAmigos(dono))
			throw new Exception(
					"O usuário não tem permissão para requisitar o empréstimo deste item");
		for (Emprestimo e : ((RepositorioRequisicaoEmprestimo) this.repositorioRequisicaoEmprestimo)
				.getRepositorio()) {
			if (e.getItem().getIDItem().equals(idItem)
					&& pedinte.equals(e.getPedinte()))
				throw new Exception("Requisição já solicitada");
		}

		Item item = ((RepositorioItem) dono.getRepositorioItem2())
				.searchOutException(idItem);
		//
		// Item item = null;
		// Usuario dono = null;
		// for(Usuario u: repositorioAmigos.getRepositorio()){
		//
		// item =
		// ((RepositorioItem)u.repositorioItem).searchOutException(idItem);
		// dono=u;
		// if(dono!=null){
		// //EU PEGAVA O ITEM AQUI
		// break;
		// }
		// }

		// TODO MUDEI AQUI BUCETA
		if (item == null) {
			throw new Exception("Item inexistente!!!!!!!!!!!");
		}// era item nulll

		if (!saoAmigos(dono)) {
			throw new Exception(
					"O usuário não tem permissão para requisitar o empréstimo deste item");
		}
		Emprestimo emprestimo = new Emprestimo(item, duracao, pedinte);// MUDEI
																		// AQUI
																		// PASSEI
																		// O
																		// PEDINTE
		emprestimo.setAprovado(false);
		((RepositorioEmprestimo) repositorioEmprestimo)
				.insertBeneficiado(emprestimo);
		// ((RepositorioEmprestimo)repositorioEmprestimo).insertEmprestador(emprestimo);

		((RepositorioEmprestimo) dono.repositorioEmprestimo)
				.insertEmprestador(emprestimo);
		// ((RepositorioEmprestimo)
		// dono.repositorioEmprestimo).insertBeneficiado(emprestimo);
		dono.getRepositorioRequisicaoEmprestimo().insert(emprestimo);
		repositorioRequisicaoEmprestimo.insert(emprestimo);
		enviarMensagem(item.getDono(), "Empréstimo do item " + item.getName()
				+ " a " + getNome(), getNome()
				+ " solicitou o empréstimo do item " + item.getName(),
				emprestimo.getIdEmprestimo());

		return emprestimo.getIdEmprestimo();
	}

	public RepositorioRequisicaoEmprestimo getRepositorioRequisicaoEmprestimo() {
		return (RepositorioRequisicaoEmprestimo) repositorioRequisicaoEmprestimo;
	}

	public String aprovarEmprestimo(String login, String idEmprestimo)
			throws Exception {
		if (!VerificadorDadosEntrada.stringValida(idEmprestimo))
			throw new Exception(
					"Identificador da requisição de empréstimo é inválido");
		Usuario aux = this;
		Emprestimo emp = ((RepositorioRequisicaoEmprestimo) repositorioRequisicaoEmprestimo)
				.search(idEmprestimo);
		if (emp == null) {
			for (Usuario us : repositorioAmigos.getRepositorio()) {
				emp = ((RepositorioEmprestimo) us.repositorioEmprestimo)
						.search(idEmprestimo);
				aux = us;
				if (emp != null)
					break;
			}
		}
		if (emp == null)
			throw new Exception("Requisição de empréstimo inexistente");
		if (emp.getDeletado())
			throw new Exception("Requisição de empréstimo inexistente");
		if (emp.getAprovado())
			throw new Exception("Empréstimo já aprovado");
		if (!emp.getItem().getDono().equals(login))
			throw new Exception(
					"O empréstimo só pode ser aprovado pelo dono do item");

		emp.setAprovado(true);
		emp.setDevolvido(false);
		emp.setRequisitouDevolucao(false);
		emp.setStatus("Andamento");

		Usuario pedinte = ((RepositorioUsuario) this.repositorioAmigos)
				.searchLogin(emp.getPedinte());
		pedinte.getRepositorioRequisicaoEmprestimo().remove(emp);

		repositorioRequisicaoEmprestimo.remove(emp);

		myHistorico.addAtividade(getNome() + " emprestou "
				+ emp.getItem().getName() + " a " + pedinte.getNome());
		return emp.getIdEmprestimo();
	}

	public void devolverItem(String idEmprestimo) throws Exception {
		Emprestimo emp = ((RepositorioEmprestimo) this.repositorioEmprestimo)
				.search(idEmprestimo);
		if (emp == null) {
			for (Usuario us : repositorioAmigos.getRepositorio()) {
				emp = ((RepositorioEmprestimo) us.repositorioEmprestimo)
						.search(idEmprestimo);
				if (emp != null)
					break;
			}
		}
		if (emp == null)
			throw new Exception("Empréstimo inexistente");
		if (emp.isDevolvido())
			throw new Exception("Item já devolvido");
		if (!((RepositorioEmprestimo) this.repositorioEmprestimo)
				.getListaEmpBeneficiado().contains(emp)) {
			throw new Exception(
					"O item só pode ser devolvido pelo usuário beneficiado");
		}
		emp.setDevolvido(true);
	}

	public void confirmarTerminoEmprestimo(String idEmprestimo)
			throws Exception {
		Emprestimo emp = ((RepositorioEmprestimo) this.repositorioEmprestimo)
				.search(idEmprestimo);
		Usuario aux = this;
		if (emp == null) {
			for (Usuario us : repositorioAmigos.getRepositorio()) {
				emp = ((RepositorioEmprestimo) us.repositorioEmprestimo)
						.search(idEmprestimo);
				aux = us;
				if (emp != null)
					break;
			}
		}
		if (emp == null)
			throw new Exception("Empréstimo inexistente");
		if (emp.getStatus().equals("Completado"))
			throw new Exception("Término do empréstimo já confirmado");
		if (!emp.getItem().getDono().equals(getLogin()))
			throw new Exception(
					"O término do empréstimo só pode ser confirmado pelo dono do item");
		if (!emp.getStatus().equals("Cancelado")) {
			emp.setStatus("Completado");
			incrementaReputacao();
		}

		Item item = emp.getItem();

		for (Interesse i : item.getRepositorioInteresses().getRepositorio()) {
			Usuario x = ((RepositorioUsuario) repositorioAmigos).searchLogin(i
					.getInteressado());
			enviarMensagem(i.getInteressado(), "O item "
					+ i.getItem().getName() + " do usuário " + getNome()
					+ " está disponível", "Not Message", x);
		}

		myHistorico.addAtividade(getNome()
				+ " confirmou o término do empréstimo do item "
				+ emp.getItem().getName());

		((RepositorioInteresse) item.getRepositorioInteresses())
				.setRepositorio(new ArrayList<Interesse>());

	}

	// US08.TXT
	public String enviarMensagem(String loginDestinatario, String assunto,
			String mensagem, Usuario destinatario) throws Exception {
		Topico topic = null;
		if (destinatario == null)
			throw new Exception("Destinatário inexistente");
		Topico aux = ((RepositorioTopicos) destinatario
				.getRepositorioMensagem()).lerTopicosPorAssunto(assunto);
		if (aux != null) {
			aux.respondeMensagem(mensagem);
			topic = aux;
		} else {
			String remetente = getLogin();
			topic = new Topico(assunto, mensagem, remetente, loginDestinatario,
					"offtopic");
			repositorioMensagem.insert(topic);
			destinatario.repositorioMensagem.insert(topic);
		}
		return topic.getIdTopic();
	}

	public String enviarMensagem(String loginDestinatario, String assunto,
			String mensagem, String idRequisicaoEmprestimo) throws Exception {
		Topico topic = null;
		Usuario user = ((RepositorioUsuario) repositorioAmigos)
				.searchLogin(loginDestinatario);
		if (user == null)
			throw new Exception("Destinatário inexistente");
		Emprestimo emprestimo = ((RepositorioEmprestimo) repositorioEmprestimo)
				.search(idRequisicaoEmprestimo);
		if (emprestimo == null) {
			for (Usuario us : repositorioAmigos.getRepositorio()) {
				emprestimo = ((RepositorioEmprestimo) us.repositorioEmprestimo)
						.search(idRequisicaoEmprestimo);
			}
		}

		if (emprestimo == null)
			throw new Exception("Requisição de empréstimo inexistente");
		if (!repositorioEmprestimo.getRepositorio().contains(emprestimo))
			throw new Exception("O usuário não participa deste empréstimo");
		Topico aux = ((RepositorioTopicos) user.getRepositorioMensagem())
				.lerTopicosPorAssunto(assunto);
		if (aux != null) {
			aux.respondeMensagem(mensagem);
			topic = aux;
		} else {
			String remetente = getLogin();
			topic = new Topico(assunto, mensagem, remetente, loginDestinatario,
					"negociacao");
			repositorioMensagem.insert(topic);
			user.repositorioMensagem.insert(topic);
		}
		return topic.getIdTopic();
	}

	public String lerTopicos(String tipo) throws Exception {
		String retorno = "";
		if (!tipo.equals("negociacao") && !tipo.equals("offtopic")
				&& !tipo.equals("todos"))
			throw new Exception("Tipo inexistente");
		else {
			retorno = ((RepositorioTopicos) getRepositorioMensagem())
					.lerTopicos(tipo);
		}
		return retorno;
	}

	public String lerMensagens(String idTopico) throws Exception {
		Topico msg = ((RepositorioTopicos) getRepositorioMensagem())
				.searchMensagem(idTopico);
		if (msg == null) {
			for (Usuario us : repositorioAmigos.getRepositorio()) {
				msg = ((RepositorioTopicos) us.getRepositorioMensagem())
						.searchMensagem(idTopico);
				if (msg != null)
					break;
			}
		}
		if (msg == null)
			throw new Exception("Tópico inexistente");
		if (!repositorioMensagem.getRepositorio().contains(msg))
			throw new Exception(
					"O usuário não tem permissão para ler as mensagens deste tópico");
		return msg.getMensagem();
	}

	// TODO
	// US09.txt
	public void requisitarDevolucao(String idEmprestimo) throws Exception {
		Emprestimo emp = ((RepositorioEmprestimo) this.repositorioEmprestimo)
				.search(idEmprestimo);
		if (emp == null) {
			for (Usuario us : repositorioAmigos.getRepositorio()) {
				emp = ((RepositorioEmprestimo) us.repositorioEmprestimo)
						.search(idEmprestimo);
				if (emp != null)
					break;
			}
		}
		if (emp == null)
			throw new Exception("Empréstimo inexistente");
		if (!getRepositorioEmprestimo().contains(emp))
			throw new Exception(
					"O usuário não tem permissão para requisitar a devolução deste item");
		if (!emp.getItem().getDono().equals(getLogin()))
			throw new Exception(
					"O usuário não tem permissão para requisitar a devolução deste item");
		if (emp.isDevolvido())
			throw new Exception("Item já devolvido");
		if (emp.getRequisitouDevolucao())
			throw new Exception("Devolução já requisitada");
		// if(emp.getTempoEmprestimo()==0)emp.setStatus("Andamento");
		// else emp.setStatus("Cancelado");
		if (emp.getTempoEmprestimo() > 0)
			emp.setStatus("Cancelado");
		Usuario pedinte = ((RepositorioUsuario) repositorioAmigos)
				.searchLogin(emp.getPedinte());
		enviarMensagem(emp.getPedinte(), "Empréstimo do item "
				+ emp.getItem().getName() + " a " + pedinte.getNome(),
				getNome() + " solicitou a devolução do item "
						+ emp.getItem().getName(), idEmprestimo);

		emp.setRequisitouDevolucao(true);
	}

	// US10.txt
	public void registrarInteresse(Item item, Usuario dono) throws Exception {

		if (item == null)
			throw new Exception("Item inexistente");
		if (this.getLogin().equals(item.getDono()))
			throw new Exception(
					"O usuário não pode registrar interesse no próprio item");

		for (Interesse i : item.getRepositorioInteresses().getRepositorio()) {
			if (i.getInteressado().equals(this.getLogin())) {
				throw new Exception(
						"O usuário já registrou interesse neste item");
			}
		}

		if (!saoAmigos(dono))
			throw new Exception(
					"O usuário não tem permissão para registrar interesse neste item");
		Interesse newInteresse = new Interesse(this.login, item);
		for (Interesse i : ((RepositorioInteresse) dono.repositorioInteresse)
				.getRepositorio()) {
			if (i.getItem().getIDItem().equals(item.getIDItem())
					&& i.getInteressado().equals(getLogin())) {
				throw new Exception(
						"O usuário já registrou interesse neste item");
			}
		}

		myHistorico.addAtividade(getNome() + " tem interesse pelo item "
				+ item.getName() + " de " + dono.getNome());

		item.getRepositorioInteresses().insert(newInteresse);

	}

	public RepositorioInteresse getRepositorioInteresse() {
		return (RepositorioInteresse) repositorioInteresse;
	}

	// US13.txt
	public void apagarItem(String idItem) throws Exception {
		boolean boll = false;
		Emprestimo emp = null;
		for (Usuario us : repositorioAmigos.getRepositorio()) {
			for (Emprestimo e : us.repositorioEmprestimo.getRepositorio()) {
				if (e.getItem().getIDItem().equals(idItem)) {
					boll = e.getAprovado();
					emp = e;
					break;
				}
			}
		}
		for (Emprestimo e : repositorioEmprestimo.getRepositorio()) {
			if (e.getItem().getIDItem().equals(idItem)) {
				boll = e.getAprovado();
				emp = e;
				break;
			}
		}
		if (boll)
			throw new Exception(
					"O usuário não pode apagar este item enquanto estiver emprestado");
		Item item = null;
		Usuario dono = null;

		for (Usuario us : repositorioAmigos.getRepositorio()) {
			for (Item i : us.repositorioItem.getRepositorio()) {
				if (i.getIDItem().equals(idItem)) {
					item = i;
					dono = us;
					break;
				}
			}
		}

		for (Item i : repositorioItem.getRepositorio()) {
			if (i.getIDItem().equals(idItem)) {
				item = i;
				dono = this;
				break;
			}
		}
		if (item == null)
			throw new Exception("Item inexistente");
		if (!dono.getLogin().equals(getLogin()))
			throw new Exception(
					"O usuário não tem permissão para apagar este item");
		if (emp != null)
			emp.deleta();
		dono.repositorioItem.remove(item);

	}

	// TODO
	public String pesquisarItem(String chave, String atributo,
			String tipoOrdenacao, String criterioOrdenacao) throws Exception {
		VerificadorDadosEntrada.verificaOrdenacao(chave, atributo,
				tipoOrdenacao, criterioOrdenacao);
		String retorno = "";
		List<Item> lista = new ArrayList<Item>();
		if (atributo.equals("nome")) {
			for (Usuario user : getRepositorioAmigos()) {
				for (Item item : user.getRepositorioItem()) {
					if (item.getName().toLowerCase()
							.contains(chave.toLowerCase())) {
						lista.add(item);
					}
				}
			}
		} else if (atributo.equals("descricao")) {
			for (Usuario user : getRepositorioAmigos()) {
				for (Item item : user.getRepositorioItem()) {
					if (item.getDescription().toLowerCase()
							.contains(chave.toLowerCase())) {
						lista.add(item);
					}
				}
			}
		} else if (atributo.equals("categoria")) {
			for (Usuario user : getRepositorioAmigos()) {
				for (Item item : user.getRepositorioItem()) {
					if (item.getCategory().toLowerCase()
							.contains(chave.toLowerCase())) {
						lista.add(item);
					}
				}
			}
		}
		if (tipoOrdenacao.equals("crescente")
				&& criterioOrdenacao.equals("reputacao"))
			comparaReputacao(lista, "crescente");
		if (tipoOrdenacao.equals("decrescente")
				&& criterioOrdenacao.equals("reputacao"))
			comparaReputacao(lista, "decrescente");
		if (tipoOrdenacao.equals("crescente")
				&& criterioOrdenacao.equals("dataCriacao"))
			comparaData(lista, "crescente");
		if (tipoOrdenacao.equals("decrescente")
				&& criterioOrdenacao.equals("dataCriacao"))
			comparaData(lista, "decrescente");
		if (lista.size() == 0) {
			retorno = "Nenhum item encontrado";
		} else {
			for (Item item : lista) {
				retorno += item.getName() + "; ";
			}
			retorno = retorno.substring(0, retorno.length() - 2);
		}
		return retorno;
	}

	private void comparaReputacao(List<Item> array, String tipoOrdenacao) {
		ArrayList<Usuario> auxi = new ArrayList<Usuario>();
		ArrayList<Item> auxiItens = new ArrayList<Item>();
		for (Item item : array) {
			auxi.add(achaDonoDeItem(item));
		}
		Collections.sort(auxi);
		for (Usuario user : auxi) {
			for (Item item : array) {
				if (user.getLogin().equals((item.getDono()))) {
					auxiItens.add(item);
				}
			}
		}
		if (tipoOrdenacao.equals("crescente")) {
			array.clear();
			for (Item item : auxiItens) {
				array.add(item);
			}
		} else if (tipoOrdenacao.equals("decrescente")) {
			array.clear();
			for (int i = auxiItens.size() - 1; i >= 0; i--) {
				array.add(auxiItens.get(i));
			}
		}
	}

	private void comparaData(List<Item> array, String tipoOrdenacao) {
		ArrayList<Item> auxiItens = new ArrayList<Item>();
		for (Item item : array) {
			auxiItens.add(item);
		}
		if (tipoOrdenacao.equals("crescente")) {
			array.clear();
			for (int i = 0; i < auxiItens.size(); i++) {
				array.add(auxiItens.get(i));
			}
		} else if (tipoOrdenacao.equals("decrescente")) {
			array.clear();
			for (int i = auxiItens.size() - 1; i >= 0; i--) {
				array.add(auxiItens.get(i));
			}
		}
	}

	public Usuario achaDonoDeItem(Item item) {
		Usuario dono = null;
		for (Item it : repositorioItem.getRepositorio()) {
			if (item.getDono().equals(it.getDono())) {
				dono = this;
			}
		}
		for (Usuario us : repositorioAmigos.getRepositorio()) {
			for (Item it : us.repositorioItem.getRepositorio()) {
				if (item.getDono().equals(it.getDono())) {
					dono = us;
				}
			}
		}
		return dono;
	}

	public void incrementaReputacao() {
		this.reputacao++;
	}

	@Override
	public int compareTo(Usuario o) {
		return reputacao - o.getReputacao();
	}

	public int getReputacao() {
		return reputacao;
	}

	public String getRaking() {
		String retorno = "";
		ArrayList<Usuario> amigos = (ArrayList) repositorioAmigos
				.getRepositorio();
		ArrayList<Usuario> clone = (ArrayList<Usuario>) amigos.clone();
		clone.add(this);
		Collections.sort(clone);
		retorno = compoeString(clone);

		if (retorno.equals("")) {
			retorno = "Não existe amigos";
		}

		return retorno;
	}

	private String compoeString(ArrayList<Usuario> lista) {
		String retorno = "";
		for (Usuario usuario : lista) {
			retorno = usuario.getLogin() + "; " + retorno;
		}

		if (!retorno.equals(""))
			retorno = retorno.substring(0, retorno.length() - 2);
		;

		return retorno;
	}

	public String historicoAtividades() {
		return this.getMyHistorico().historicoAtividades();
	}

	public String historicoAtividadesConjunto() {
		Map<Integer, String> atividadeConjunta = new HashMap<Integer, String>();
		atividadeConjunta.putAll(myHistorico.getHistoricoPorCadastro());
		for (Usuario amigo : repositorioAmigos.getRepositorio()) {
			atividadeConjunta.putAll(amigo.getMyHistorico()
					.getHistoricoPorCadastro());
		}
		String HistoricoTotal = "";
		List<Integer> auxi = new ArrayList<Integer>();
		for (Integer key : atividadeConjunta.keySet()) {
			auxi.add(key);
		}
		Collections.sort(auxi);
		List<String> repeticoes = new ArrayList<String>();
		for (int i = auxi.size() - 1; i >= 0; i--) {

			if (atividadeConjunta.get(auxi.get(i)).contains("são amigos")
					&& !atividadeConjunta.get(auxi.get(i))
							.substring(0, getNome().length()).equals(getNome())
					&& atividadeConjunta.get(auxi.get(i)).contains(getNome()))
				;
			else {
				boolean tem = false;
				for (String x : repeticoes) {
					if (x.equals(atividadeConjunta.get(auxi.get(i)))) {
						tem = true;
						break;
					}
				}
				if (!tem)
					HistoricoTotal += atividadeConjunta.get(auxi.get(i)) + "; ";
				if (atividadeConjunta.get(auxi.get(i)).contains(
						"precisa do item"))
					repeticoes.add(atividadeConjunta.get(auxi.get(i)));
			}
		}

		return HistoricoTotal.length() > 0 ? HistoricoTotal.substring(0,
				HistoricoTotal.length() - 2) : "Não há atividades";
	}

	public String publicarPedido(String nomeItem, String descricaoItem)
			throws Exception {
		VerificadorDadosEntrada.verificaPublicarPedido(nomeItem, descricaoItem);
		Publicacao publi = ((RepositorioPublicacao) repositorioPublicacoes)
				.searchPorDescricao(nomeItem, descricaoItem);
		if (publi != null)
			throw new Exception("JA EXISTE ESSA PUBLICACAO");
		Publicacao publicacao = new Publicacao(nomeItem, descricaoItem);
		publicacao.setNomeDonoPublicacao(getNome());
		publicacao.setLoginDonoPublicacao(getLogin());
		repositorioPublicacoes.insert(publicacao);
		myHistorico.addAtividade(getNome() + " precisa do item " + nomeItem);
		return publicacao.getIdPublicacaoPedido();
	}

	public void rePublicarPedido(String idPublicacao) throws Exception {
		Publicacao pub = ((RepositorioPublicacao) repositorioPublicacoes)
				.search(idPublicacao);
		if (pub != null)
			throw new Exception("JA EXISTE ESSA PUBLICACAO");
		Publicacao publicacao = null;
		for (Usuario us : getRepositorioAmigos()) {
			publicacao = ((RepositorioPublicacao) us.repositorioPublicacoes)
					.search(idPublicacao);
			if (publicacao != null)
				break;
		}
		repositorioPublicacoes.insert(publicacao);
		myHistorico.addAtividade(publicacao.getNomeDonoPublicacao()
				+ " precisa do item " + publicacao.getNomeItem());
	}

	public void oferecerItem(String idPublicacaoPedido, String idItem,
			Usuario destinatario, Publicacao publicac) throws Exception {
		Item item = null;
		Publicacao publicacao = publicac;
		if (publicacao == null)
			throw new Exception("Publicação de pedido inexistente");
		item = ((RepositorioItem) repositorioItem).search(idItem);
		if (item == null)
			throw new Exception("Item inexistente");
		enviarMensagem(
				destinatario.getLogin(),
				"O usuário " + getNome() + " ofereceu o item "
						+ publicacao.getNomeItem(),
				"Item oferecido: " + publicacao.getNomeItem() + " - "
						+ item.getDescription(), destinatario);
	}

	public void setName(String string) throws Exception{
		if(!VerificadorDadosEntrada.stringValida(string))throw new Exception("Nome inválido");
		this.nome = string;

	}

	public void setLogin(String string) throws Exception {
		VerificadorDadosEntrada.verificaLogin(string);
		this.login = string;

	}

	public void setEndereco(String string) throws Exception {
		if(!VerificadorDadosEntrada.stringValida(string))throw new Exception("Endereco inválido");
		this.endereco = string;

	}

}
